package jmine.tec.script.persistent.pack;

import java.util.Arrays;
import java.util.Collections;

import jmine.tec.database.pack.populator.AbstractPopulatorDataSource;
import jmine.tec.database.pack.populator.PopulatorBean;
import jmine.tec.script.persistent.dao.ScriptDAO;
import jmine.tec.script.persistent.dao.ScriptLanguageIdentifier;
import jmine.tec.script.persistent.domain.Script;
import jmine.tec.utils.collection.Mapper;
import jmine.tec.utils.collection.MapperUtils;
import jmine.tec.utils.dependency.DependencyGraph;

/**
 * Populador de pacotes que envia scripts para serem salvos.
 * 
 * @author lundberg
 */
public class ScriptPopulatorDataSource extends AbstractPopulatorDataSource<Script> {

    private ScriptDAO scriptDAO;

    private ScriptLanguageIdentifier language;

    /**
     * {@inheritDoc}
     */
    public Iterable<PopulatorBean<Script>> load() {
        DependencyGraph<Script> graph = new DependencyGraph<Script>();
        for (Script script : this.scriptDAO.findPackScripts(this.language)) {
            graph.addValuesSkipCheck(Collections.singletonList(script));
            for (Script api : script.getApis()) {
                graph.addValuesSkipCheck(Arrays.asList(api, script));
            }
        }
        return MapperUtils.mapList(graph.getTopologicalOrder(), new Mapper<Script, PopulatorBean<Script>>() {
            public PopulatorBean<Script> apply(Script script) {
                String fileName = script.getMnemonico() + "." + script.getLanguage().getAbreviacao().toLowerCase();
                return new PopulatorBean<Script>(script, "scripts", fileName);
            }
        });
    }

    /**
     * @param language the language to set
     */
    public void setLanguage(ScriptLanguageIdentifier language) {
        this.language = language;
    }

    /**
     * @param scriptDAO the scriptDAO to set
     */
    public void setScriptDAO(ScriptDAO scriptDAO) {
        this.scriptDAO = scriptDAO;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + ((this.language == null) ? 0 : this.language.hashCode());
        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object obj) {
        if (!super.equals(obj)) {
            return false;
        }
        ScriptPopulatorDataSource o = (ScriptPopulatorDataSource) obj;
        return this.language.equals(o.language);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return String.format("ScriptPopulatorDataSource:[language=%s]", this.language);
    }

}
